﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using System.Web;
using log4net;
using Newtonsoft.Json;
using StackExchange.Redis;

namespace ASP.NET_MVC_Static_Test.Common
{
    public class RedisHelper
    {
        private static readonly ILog logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

        private static object lockHelp = new object();
        private ConnectionMultiplexer _connectionMultiplexer = null;
        private readonly string _connName = $"redisStr";
      

        private ConnectionMultiplexer Connection
        {
            get
            {
                if (_connectionMultiplexer == null)
                {
                    lock (lockHelp)
                    {
                        if (_connectionMultiplexer == null)
                        {
                            string connstr = "";
                            if (!string.IsNullOrEmpty(_connName))
                            {
                                connstr = ConfigurationManager.AppSettings[_connName];
                            }

                            _connectionMultiplexer = ConnectionMultiplexer.Connect(connstr);

                            //注册如下事件
                            _connectionMultiplexer.ConnectionFailed += MuxerConnectionFailed;
                            _connectionMultiplexer.ConnectionRestored += MuxerConnectionRestored;
                            _connectionMultiplexer.ErrorMessage += MuxerErrorMessage;
                            _connectionMultiplexer.HashSlotMoved += MuxerHashSlotMoved;
                            _connectionMultiplexer.InternalError += MuxerInternalError;
                        }
                    }
                }

                return _connectionMultiplexer;
            }
        }

        private IDatabase Cache => Connection.GetDatabase();

        /// <summary>
        /// 返回事务批处理
        /// </summary>
        /// <returns></returns>
        public IBatch GetBatch()
        {
            return Cache.CreateBatch();
        }

        #region lock

        /// <summary>
        /// 获取锁
        /// </summary>
        /// <param name="key"></param>
        /// <param name="seconds">锁的过期时间</param>
        /// <param name="value">单位 秒</param>
        /// <returns></returns>
        public bool LockTake(string key, int seconds, string value = "1")
        {
            if (seconds <= 0) throw new Exception("senconds 必须为正整数");
            return Cache.StringSet(key, value, new TimeSpan(0, 0, seconds), When.NotExists);
        }

        /// <summary>
        /// 获取锁
        /// </summary>
        /// <param name="key"></param>
        /// <param name="seconds">锁的过期时间</param>
        /// <param name="value">单位 秒</param>
        /// <returns></returns>
        public async Task<bool> LockTakeAsync(string key, int seconds, string value = "1")
        {
            if (seconds <= 0) throw new Exception("senconds 必须为正整数");
            return await Cache.StringSetAsync(key, value, new TimeSpan(0, 0, seconds), When.NotExists);
        }

        /// <summary>
        /// 释放锁
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public bool LockRelease(string key)
        {
            return Cache.KeyDelete(key);
        }

        /// <summary>
        /// 释放锁 
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public async Task<bool> LockReleaseAsync(string key)
        {
            return await Cache.KeyDeleteAsync(key);
        }

        /// <summary>
        /// 延长锁时间
        /// </summary>
        /// <param name="key"></param>
        /// <param name="seconds">锁的延长过期时间 单位 秒</param>
        /// <returns></returns>
        public bool LockExtend(string key, int seconds)
        {
            if (seconds <= 0) throw new Exception("senconds 必须为正整数");
            return Cache.KeyExpire(key, new TimeSpan(0, 0, seconds));
        }

        /// <summary>
        /// 延长锁时间
        /// </summary>
        /// <param name="key"></param>
        /// <param name="seconds">锁的延长过期时间 单位 秒</param>
        /// <returns></returns>
        public async Task<bool> LockExtendAsync(string key, int seconds)
        {
            if (seconds <= 0) throw new Exception("senconds 必须为正整数");
            return await Cache.KeyExpireAsync(key, new TimeSpan(0, 0, seconds));
        }

        #endregion

        #region keys


        //public  List<string> Keys(string pattern)
        //{
        // var server=   _connectionMultiplexer.GetServer(_connectionMultiplexer.GetEndPoints())
        //    var list = server.Keys(_connectionMultiplexer.d, pattern).ToArray();
        //    return Array.ConvertAll<RedisKey, string>(list, x => x).ToList();
        //}

        /// <summary>
        /// 重命名 key
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public bool KeyRename(string key, string newKey)
        {
            return Cache.KeyRename(key, newKey);
        }

        /// <summary>
        /// 删除 key
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public bool KeyDelete(string key)
        {
            return Cache.KeyDelete(key);
        }

        /// <summary>
        /// 删除 key
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public async Task<bool> KeyDeleteAsync(string key)
        {
            return await Cache.KeyDeleteAsync(key);
        }

        /// <summary>
        /// 是否存在 key
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public bool KeyExists(string key)
        {
            return Cache.KeyExists(key);
        }

        /// <summary>
        /// 是否存在 key
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public async Task<bool> KeyExistsAsync(string key)
        {
            return await Cache.KeyExistsAsync(key);
        }

        /// <summary>
        /// 设置过期时间
        /// </summary>
        /// <param name="key"></param>
        /// <param name="expiresAt"></param>
        public void KeyExpire(string key, DateTime expiresAt)
        {
            Cache.KeyExpire(key, expiresAt);
        }

        /// <summary>
        /// 设置过期时间
        /// </summary>
        /// <param name="key"></param>
        /// <param name="expiresAt"></param>
        public void KeyExpire(string key, TimeSpan expiresAt)
        {
            Cache.KeyExpire(key, expiresAt);
        }

        /// <summary>
        /// 设置过期时间
        /// </summary>
        /// <param name="key"></param>
        /// <param name="expiresAt"></param>
        /// <returns></returns>
        public async Task<bool> KeyExpireAsync(string key, DateTime expiresAt)
        {
            return await Cache.KeyExpireAsync(key, expiresAt);
        }

        #endregion

        #region string

        /// <summary>
        /// 获取值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        public T Get<T>(string key)
        {
            return DeserializeObject<T>(Cache.StringGet(key));
        }

        /// <summary>
        /// 获取值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        public async Task<T> GetAsync<T>(string key)
        {
            return DeserializeObject<T>(await Cache.StringGetAsync(key));
        }

        /// <summary>
        /// 批量获取值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="keys"></param>
        /// <returns></returns>
        public List<T> Get<T>(string[] keys)
        {
            List<T> list = new List<T>();
            var dir = Cache.StringGet(Array.ConvertAll<string, RedisKey>(keys, x => x));
            if (dir != null && dir.Length > 0)
            {
                foreach (var info in dir)
                {
                    var item = DeserializeObject<T>(info.ToString());
                    if (!object.Equals(item, default(T)))
                        list.Add(item);
                }
            }
            return list;
        }

        /// <summary>
        /// 批量获取值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="keys"></param>
        /// <returns></returns>
        public async Task<List<T>> GetAsync<T>(string[] keys)
        {
            List<T> list = new List<T>();
            var dir = await Cache.StringGetAsync(Array.ConvertAll<string, RedisKey>(keys, x => x));
            if (dir != null && dir.Length > 0)
            {
                foreach (var info in dir)
                {
                    var item = DeserializeObject<T>(info.ToString());
                    if (!object.Equals(item, default(T)))
                        list.Add(item);
                }
            }
            return list;
        }

        //set

        /// <summary>
        /// 设置值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="ms"></param>
        /// <returns></returns>
        public bool Set<T>(string key, T value, long? ms = null)
        {
            if (ms == null || ms.Value == 0)
                return Cache.StringSet(key, SerializeObject(value));
            else
                return Cache.StringSet(key, SerializeObject(value), TimeSpan.FromMinutes(ms.Value));
        }

        /// <summary>
        /// 设置值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="ms"></param>
        /// <returns></returns>
        public async Task<bool> SetAsync<T>(string key, T value, int? ms = null)
        {
            if (ms == null || ms.Value == 0)
                return await Cache.StringSetAsync(key, SerializeObject(value));
            else
                return await Cache.StringSetAsync(key, SerializeObject(value), TimeSpan.FromMinutes(ms.Value));
        }

        /// <summary>
        /// 自增操作 默认1
        /// </summary>
        /// <param name="key"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        public long Increment(string key, int count = 1)
        {
            return Cache.StringIncrement(key, count);
        }

        /// <summary>
        /// 自增操作 默认1
        /// </summary>
        /// <param name="key"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        public async Task<long> IncrementAsync(string key, int count = 1)
        {
            return await Cache.StringIncrementAsync(key, count);
        }

        /// <summary>
        /// 自减操作 默认1
        /// </summary>
        /// <param name="key"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        public long Decrement(string key, int count = 1)
        {
            return Cache.StringDecrement(key, count);
        }

        /// <summary>
        /// 自减操作 默认1
        /// </summary>
        /// <param name="key"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        public async Task<long> DecrementAsync(string key, int count = 1)
        {
            return await Cache.StringDecrementAsync(key, count);
        }

        #endregion

        #region hash

        //get

        /// <summary>
        /// hash 数量
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public long HashLength(string key)
        {
            return Cache.HashLength(key);
        }

        /// <summary>
        /// hash数量
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public async Task<long> HashLengthAsync(string key)
        {
            return await Cache.HashLengthAsync(key);
        }

        /// <summary>
        /// 是否存在field
        /// </summary>
        /// <param name="key"></param>
        /// <param name="field"></param>
        /// <returns></returns>
        public bool HashExists(string key, string field)
        {
            return Cache.HashExists(key, field);
        }

        /// <summary>
        /// 是否存在field
        /// </summary>
        /// <param name="key"></param>
        /// <param name="field"></param>
        /// <returns></returns>
        public async Task<bool> HashExistsAsync(string key, string field)
        {
            return await Cache.HashExistsAsync(key, field);
        }

        /// <summary>
        /// 获取值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public T HashGet<T>(string key, string value)
        {
            return DeserializeObject<T>(Cache.HashGet(key, value));
        }

        /// <summary>
        /// 获取值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public async Task<T> HashGetAsync<T>(string key, string value)
        {
            return DeserializeObject<T>(await Cache.HashGetAsync(key, value));
        }

        /// <summary>
        /// 批量获取值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public List<T> HashGet<T>(string key, string[] value)
        {
            List<T> list = new List<T>();
            var dir = Cache.HashGet(key, Array.ConvertAll<string, RedisValue>(value, x => x));
            if (dir != null && dir.Length > 0)
            {
                foreach (var info in dir)
                {
                    var item = DeserializeObject<T>(info.ToString());
                    if (!object.Equals(item, default(T)))
                        list.Add(item);
                }
            }
            return list;
        }

        /// <summary>
        /// 批量获取值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public async Task<List<T>> HashGetAsync<T>(string key, string[] value)
        {
            List<T> list = new List<T>();
            var dir = await Cache.HashGetAsync(key, Array.ConvertAll<string, RedisValue>(value, x => x));
            if (dir != null && dir.Length > 0)
            {
                foreach (var info in dir)
                {
                    var item = DeserializeObject<T>(info.ToString());
                    if (!object.Equals(item, default(T)))
                        list.Add(item);
                }
            }
            return list;
        }

        /// <summary>
        /// 全部获取值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        public Dictionary<string, T> HashGetAll<T>(string key)
        {
            HashEntry[] value = Cache.HashGetAll(key);

            Dictionary<string, T> dict = new Dictionary<string, T>();

            if (value != null && value.Length > 0)
            {
                foreach (var item in value)
                    dict.Add(item.Name, DeserializeObject<T>(item.Value));
            }

            return dict;
        }

        /// <summary>
        /// 全部获取值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        public async Task<Dictionary<string, T>> HashGetAllAsync<T>(string key)
        {
            HashEntry[] value = await Cache.HashGetAllAsync(key);

            Dictionary<string, T> dict = new Dictionary<string, T>();

            if (value != null && value.Length > 0)
            {
                foreach (var item in value)
                    dict.Add(item.Name, DeserializeObject<T>(item.Value));
            }

            return dict;
        }

        //set

        /// <summary>
        /// 删除值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="field"></param>
        /// <returns></returns>
        public bool HashDelete(string key, string field)
        {
            return Cache.HashDelete(key, field);
        }

        /// <summary>
        /// 删除值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="field"></param>
        /// <returns></returns>
        public async Task<bool> HashDeleteAsync(string key, string field)
        {
            return await Cache.HashDeleteAsync(key, field);
        }

        /// <summary>
        /// 设置值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="field"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool HashSet<T>(string key, string field, T value)
        {
            return Cache.HashSet(key, field, SerializeObject(value));
        }

        /// <summary>
        /// 设置值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="field"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public async Task<bool> HashSetAsync<T>(string key, string field, T value)
        {
            return await Cache.HashSetAsync(key, field, SerializeObject(value));
        }

        /// <summary>
        /// 批量设置值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="dictionary"></param>
        public void HashSet<T>(string key, Dictionary<string, T> dictionary)
        {
            List<HashEntry> list = new List<HashEntry>();

            foreach (KeyValuePair<string, T> item in dictionary)
                list.Add(new HashEntry(item.Key, SerializeObject(item.Value)));

            Cache.HashSet(key, list.ToArray());
        }

        /// <summary>
        /// 批量设置值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="dictionary"></param>
        /// <returns></returns>
        public async Task HashSetAsync<T>(string key, Dictionary<string, T> dictionary)
        {
            List<HashEntry> list = new List<HashEntry>();

            foreach (KeyValuePair<string, T> item in dictionary)
                list.Add(new HashEntry(item.Key, SerializeObject(item.Value)));

            await Cache.HashSetAsync(key, list.ToArray());
        }

        /// <summary>
        /// 自增操作 默认1
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        public long HashIncrement(string key, string value, int count = 1)
        {
            return Cache.HashIncrement(key, value, count);
        }

        /// <summary>
        /// 自增操作 默认1
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        public async Task<long> HashIncrementAsync(string key, string value, int count = 1)
        {
            return await Cache.HashIncrementAsync(key, value, count);
        }

        /// <summary>
        /// 自减操作 默认1
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        public long HashDecrement(string key, string value, int count = 1)
        {
            return Cache.HashDecrement(key, value, count);
        }

        /// <summary>
        /// 自减操作 默认1
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        public async Task<long> HashDecrementAsync(string key, string value, int count = 1)
        {
            return await Cache.HashDecrementAsync(key, value, count);
        }

        #region

        /// <summary>
        /// 设置一个实体 到hash
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="objInfo"></param>
        public void SetModelToHash<T>(string key, T objInfo) where T : class
        {
            Type types = objInfo.GetType();
            PropertyInfo[] cfields = types.GetProperties(BindingFlags.Public | BindingFlags.Instance);
            Dictionary<string, string> formdata = cfields.ToDictionary(info => info.Name, info => SerializeObject(info.GetValue(objInfo, null)));

            var nameList = new List<HashEntry>();
            foreach (var field in formdata)
            {
                nameList.Add(new HashEntry(field.Key, field.Value));
            }
            Cache.HashSet(key, nameList.ToArray());
        }

        /// <summary>
        /// 设置一个实体 到hash
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="objInfo"></param>
        public void SetModelToHashAsync<T>(string key, T objInfo) where T : class
        {
            Type types = objInfo.GetType();
            PropertyInfo[] cfields = types.GetProperties(BindingFlags.Public | BindingFlags.Instance);
            Dictionary<string, string> formdata = cfields.ToDictionary(info => info.Name, info => SerializeObject(info.GetValue(objInfo, null)));

            var nameList = new List<HashEntry>();
            foreach (var field in formdata)
            {
                if (field.Value != null)
                    nameList.Add(new HashEntry(field.Key, field.Value));
            }
            Cache.HashSetAsync(key, nameList.ToArray());
        }

        /// <summary>
        /// 批量设置实体 到hash
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dictionary"></param>
        public void SetBatchModelInHash<T>(Dictionary<string, T> dictionary)
        {
            var batch = Cache.CreateBatch();

            foreach (KeyValuePair<string, T> pair in dictionary)
            {
                if (!string.IsNullOrEmpty(pair.Key))
                {
                    Type types = pair.Value.GetType();
                    PropertyInfo[] cfields = types.GetProperties(BindingFlags.Public | BindingFlags.Instance);
                    Dictionary<string, string> formdata = cfields.ToDictionary(info => info.Name, info => SerializeObject(info.GetValue(pair.Value, null)));

                    var nameList = new List<HashEntry>();
                    foreach (var field in formdata)
                        nameList.Add(new HashEntry(field.Key, field.Value));

                    batch.HashSetAsync(pair.Key, nameList.ToArray());
                }
            }

            batch.Execute();
        }

        public T GetInfoFromHash<T>(string hashId) where T : class, new()
        {
            var reModel = new T();
            try
            {
                var types = reModel.GetType();
                var cfields = types.GetProperties(BindingFlags.Public | BindingFlags.Instance);
                var nameList = new List<RedisValue>();
                foreach (var field in cfields)
                {
                    nameList.Add(field.Name);
                }
                var result = Cache.HashGet(hashId, nameList.ToArray());
                reModel = GetHashInfo<T>(cfields, result);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return reModel;
        }

        /// <summary>
        /// 从hash批量获取实体
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="keys"></param>
        /// <returns></returns>
        public List<T> GetBatchInfoFromHash<T>(string[] hashIds) where T : class, new()
        {
            var reObjs = new List<T>();
            var reModel = new T();
            try
            {
                var types = reModel.GetType();
                var cfields = types.GetProperties(BindingFlags.Public | BindingFlags.Instance);
                var nameList = new List<RedisValue>();
                foreach (var info in cfields)
                {
                    nameList.Add(info.Name);
                }
                var listValue = new List<Task<RedisValue[]>>();
                var batch = Cache.CreateBatch();
                foreach (var hashId in hashIds)
                {
                    var task = batch.HashGetAsync(hashId, nameList.ToArray());
                    listValue.Add(task);
                }
                batch.Execute();

                foreach (var task in listValue)
                {
                    var result = task.Result;
                    if (result != null)
                    {
                        reModel = GetHashInfo<T>(cfields, result);
                        reObjs.Add(reModel);
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return reObjs;
        }

        /// <summary>
        ///     设置hash对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="cfields"></param>
        /// <param name="result"></param>
        private static T GetHashInfo<T>(PropertyInfo[] cfields, RedisValue[] result)
            where T : class, new()
        {
            var reModel = new T();
            var ii = 0;
            foreach (var info in cfields)
            {
                var type = info.PropertyType;
                var fromVal = result[ii];

                try
                {
                    try
                    {
                        if (type.FullName == "System.String")
                        {
                            if (fromVal.IsNull)
                            {
                                ii++;
                                continue;
                            }
                            info.SetValue(reModel, fromVal.ToString());
                        }
                        else
                        {
                            if (fromVal.IsNullOrEmpty)
                            {
                                ii++;
                                continue;
                            }
                            var toVal = JsonConvert.DeserializeObject(fromVal.ToString(), type);
                            info.SetValue(reModel, toVal);
                        }
                    }
                    catch
                    {
                        info.SetValue(reModel, fromVal.ToString());
                    }
                    ii++;
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }
            return reModel;
        }

        #endregion

        #endregion

        #region list

        //set

        /// <summary>
        /// 插入到值前面
        /// </summary>
        /// <param name="key"></param>
        /// <param name="pivot"></param>
        /// <param name="value"></param>
        /// <returns>成功返回数量，失败返回-1</returns>
        public long ListInsertBefore(string key, string pivot, string value)
        {
            return Cache.ListInsertBefore(key, pivot, value);
        }

        /// <summary>
        /// 插入到值前面
        /// </summary>
        /// <param name="key"></param>
        /// <param name="pivot"></param>
        /// <param name="value"></param>
        /// <returns>成功返回数量，失败返回-1</returns>
        public async Task<long> ListInsertBeforeAsync(string key, string pivot, string value)
        {
            return await Cache.ListInsertBeforeAsync(key, pivot, value);
        }

        /// <summary>
        /// 插入到值后面
        /// </summary>
        /// <param name="key"></param>
        /// <param name="pivot"></param>
        /// <param name="value"></param>
        /// <returns>成功返回数量，失败返回-1</returns>
        public long ListInsertAfter(string key, string pivot, string value)
        {
            return Cache.ListInsertAfter(key, pivot, value);
        }

        /// <summary>
        /// 插入到值后面
        /// </summary>
        /// <param name="key"></param>
        /// <param name="pivot"></param>
        /// <param name="value"></param>
        /// <returns>成功返回数量，失败返回-1</returns>
        public async Task<long> ListInsertAfterAsync(string key, string pivot, string value)
        {
            return await Cache.ListInsertAfterAsync(key, pivot, value);
        }

        /// <summary>
        /// 左边插入值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns>返回数量</returns>
        public long ListLeftPush(string key, string value)
        {
            return Cache.ListLeftPush(key, value);
        }

        /// <summary>
        /// 左边插入值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns>返回数量</returns>
        public long ListLeftPush(string key, string[] value)
        {
            return Cache.ListLeftPush(key, Array.ConvertAll<string, RedisValue>(value, x => x));
        }

        /// <summary>
        /// 左边插入值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns>返回数量</returns>
        public async Task<long> ListLeftPushAsync(string key, string value)
        {
            return await Cache.ListLeftPushAsync(key, value);
        }

        /// <summary>
        /// 右边插入值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns>返回数量</returns>
        public long ListRightPush(string key, string value)
        {
            return Cache.ListRightPush(key, value);
        }

        /// <summary>
        /// 右边插入值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns>返回数量</returns>
        public long ListRightPush(string key, string[] value)
        {
            return Cache.ListRightPush(key, Array.ConvertAll<string, RedisValue>(value, x => x));
        }

        /// <summary>
        /// 右边插入值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns>返回数量</returns>
        public async Task<long> ListRightPushAsync(string key, string value)
        {
            return await Cache.ListRightPushAsync(key, value);
        }

        /// <summary>
        /// 删除值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns>返回删除的数量</returns>
        public long ListRemove(string key, string value)
        {
            return Cache.ListRemove(key, value);
        }

        /// <summary>
        /// 删除值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns>返回删除的数量</returns>
        public async Task<long> ListRemoveAsync(string key, string value)
        {
            return await Cache.ListRemoveAsync(key, value);
        }

        /// <summary>
        /// 设置索引值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="index"></param>
        /// <param name="value"></param>
        public void ListSetByIndex(string key, long index, string value)
        {
            Cache.ListSetByIndex(key, index, value);
        }

        /// <summary>
        /// 设置索引值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="index"></param>
        /// <param name="value"></param>
        public async Task ListSetByIndexAsync(string key, long index, string value)
        {
            await Cache.ListSetByIndexAsync(key, index, value);
        }

        /// <summary>
        /// LTRIM
        ///对一个列表进行修剪(trim)，就是说，让列表只保留指定区间内的元素，不在指定区间之内的元素都将被删除
        /// </summary>
        /// <param name="key"></param>
        /// <param name="star"></param>
        /// <param name="end"></param>
        public void ListTrim(string key, int star, int end)
        {
            Cache.ListTrim(key, star, end);
        }

        /// <summary>
        /// LTRIM
        ///对一个列表进行修剪(trim)，就是说，让列表只保留指定区间内的元素，不在指定区间之内的元素都将被删除
        /// </summary>
        /// <param name="key"></param>
        /// <param name="star"></param>
        /// <param name="end"></param>
        public async Task ListTrimAsync(string key, int star, int end)
        {
            await Cache.ListTrimAsync(key, star, end);
        }

        //get

        /// <summary>
        /// 左边取值
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public string ListLeftPop(string key)
        {
            return Cache.ListLeftPop(key);
        }

        /// <summary>
        /// 左边取值
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public async Task<string> ListLeftPopAsync(string key)
        {
            return await Cache.ListLeftPopAsync(key);
        }

        /// <summary>
        /// 右边取值
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>

        public string ListRightPop(string key)
        {
            return Cache.ListRightPop(key);
        }

        /// <summary>
        /// 右边取值
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>

        public async Task<string> ListRightPopAsync(string key)
        {
            return await Cache.ListRightPopAsync(key);
        }

        /// <summary>
        /// 队列数量
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public long ListLength(string key)
        {
            return Cache.ListLength(key);
        }

        /// <summary>
        /// 队列数量
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public async Task<long> ListLengthAsync(string key)
        {
            return await Cache.ListLengthAsync(key);
        }

        /// <summary>
        /// LRANGE
        /// 返回列表 key 中指定区间内的元素，区间以偏移量 start 和 stop 指定
        /// </summary>
        /// <param name="key"></param>
        /// <param name="star"></param>
        /// <param name="end"></param>
        /// <returns></returns>
        public List<string> ListRange(string key, int star, int end)
        {
            List<string> list = new List<string>();

            var value = Cache.ListRange(key, star, end);

            foreach (var item in value)
                list.Add(item);

            return list;
        }

        /// <summary>
        /// LRANGE
        /// 返回列表 key 中指定区间内的元素，区间以偏移量 start 和 stop 指定
        /// </summary>
        /// <param name="key"></param>
        /// <param name="star"></param>
        /// <param name="end"></param>
        /// <returns></returns>
        public async Task<List<string>> ListRangeAsync(string key, int star, int end)
        {
            List<string> list = new List<string>();

            var value = await Cache.ListRangeAsync(key, star, end);

            foreach (var item in value)
                list.Add(item);

            return list;
        }

        /// <summary>
        /// 获取索引值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="index"></param>
        /// <returns></returns>
        public string ListGetByIndex(string key, long index)
        {
            return (string)Cache.ListGetByIndex(key, index);
        }

        /// <summary>
        /// 获取索引值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="index"></param>
        /// <returns></returns>
        public async Task<string> ListGetByIndexAsync(string key, long index)
        {
            return (string)await Cache.ListGetByIndexAsync(key, index);
        }

        #endregion list

        #region Sorted Sets

        //set

        /// <summary>
        /// 增加值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="score"></param>
        /// <returns></returns>
        public bool SortedSetAdd(string key, string value, double score)
        {
            return Cache.SortedSetAdd(key, value, score);
        }

        /// <summary>
        /// 增加值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="score"></param>
        /// <returns></returns>
        public async Task<bool> SortedSetAddAsync(string key, string value, double score)
        {
            return await Cache.SortedSetAddAsync(key, value, score);
        }

        /// <summary>
        /// 自增操作
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="count">默认1</param>
        /// <returns></returns>
        public double SortedSetIncrement(string key, string value, double count = 1)
        {
            return Cache.SortedSetIncrement(key, value, count);
        }

        /// <summary>
        /// 自增操作
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="count">默认1</param>
        /// <returns></returns>
        public async Task<double> SortedSetIncrementAsync(string key, string value, double count = 1)
        {
            return await Cache.SortedSetIncrementAsync(key, value, count);
        }

        /// <summary>
        /// 自减操作
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        public double SortedSetDecrement(string key, string value, double count = 1)
        {
            return Cache.SortedSetDecrement(key, value, count);
        }

        /// <summary>
        /// 自减操作
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        public async Task<double> SortedSetDecrementAsync(string key, string value, double count = -1)
        {
            return await Cache.SortedSetDecrementAsync(key, value, count);
        }

        /// <summary>
        /// 批量添加值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="dictionary"></param>
        /// <returns></returns>
        public long SortedSetAdd(string key, IDictionary<string, double> dictionary)
        {
            List<SortedSetEntry> list = new List<SortedSetEntry>();

            foreach (KeyValuePair<string, double> item in dictionary)
                list.Add(new SortedSetEntry(item.Key, item.Value));

            return Cache.SortedSetAdd(key, list.ToArray());
        }

        /// <summary>
        /// 批量添加值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="dictionary"></param>
        /// <returns></returns>
        public async Task<long> SortedSetAddAsync(string key, IDictionary<string, double> dictionary)
        {
            List<SortedSetEntry> list = new List<SortedSetEntry>();

            foreach (KeyValuePair<string, double> item in dictionary)
                list.Add(new SortedSetEntry(item.Key, item.Value));

            return await Cache.SortedSetAddAsync(key, list.ToArray());
        }

        /// <summary>
        /// 删除值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool SortedSetRemove(string key, string value)
        {
            return Cache.SortedSetRemove(key, value);
        }

        /// <summary>
        /// 删除值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public async Task<bool> SortedSetRemoveAsync(string key, string value)
        {
            return await Cache.SortedSetRemoveAsync(key, value);
        }

        /// <summary>
        /// 删除分数段的值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="start"></param>
        /// <param name="stop"></param>
        /// <returns></returns>
        public long SortedSetRemoveRangeByScore(string key, double start, double stop)
        {
            return Cache.SortedSetRemoveRangeByScore(key, start, stop);
        }

        /// <summary>
        /// 删除分数段的值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="start"></param>
        /// <param name="stop"></param>
        /// <returns>返回删除数量</returns>
        public async Task<long> SortedSetRemoveRangeByScoreAsync(string key, double start, double stop)
        {
            return await Cache.SortedSetRemoveRangeByScoreAsync(key, start, stop);
        }

        /// <summary>
        /// 删除排名段的值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="start"></param>
        /// <param name="stop"></param>
        /// <returns>返回删除数量</returns>
        public long SortedSetRemoveRangeByRank(string key, long start, long stop)
        {
            return Cache.SortedSetRemoveRangeByRank(key, start, stop);
        }

        /// <summary>
        /// 删除排名段的值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="start"></param>
        /// <param name="stop"></param>
        /// <returns>返回删除数量</returns>
        public async Task<long> SortedSetRemoveRangeByRankAsync(string key, long start, long stop)
        {
            return await Cache.SortedSetRemoveRangeByRankAsync(key, start, stop);
        }

        //get

        /// <summary>
        /// 获取分值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns>没分值 返回-1</returns>
        public double SortedSetScore(string key, string value)
        {
            var score = Cache.SortedSetScore(key, value);
            return score == null ? -1 : score.Value;
        }

        /// <summary>
        /// 获取分值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns>没分值 返回-1</returns>
        public async Task<double> SortedSetScoreAsync(string key, string value)
        {
            var score = await Cache.SortedSetScoreAsync(key, value);
            return score == null ? -1 : score.Value;
        }

        /// <summary>
        /// 获取排名 默认升序
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="order">0升序 1降序</param>
        /// <returns>没排名 返回 -1</returns>
        public long SortedSetRank(string key, string value, int order = 0)
        {
            var rank = Cache.SortedSetRank(key, value, (Order)order);

            return rank == null ? -1 : rank.Value;
        }

        /// <summary>
        /// 获取排名 默认升序
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="order">0升序 1降序</param>
        /// <returns>没排名 返回 -1</returns>
        public async Task<long> SortedSetRankAsync(string key, string value, int order = 0)
        {
            var rank = await Cache.SortedSetRankAsync(key, value, (Order)order);

            return rank == null ? -1 : rank.Value;
        }

        /// <summary>
        /// 集合数量
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public long SortedSetLength(string key)
        {
            return Cache.SortedSetLength(key);
        }

        /// <summary>
        /// 集合数量
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public async Task<long> SortedSetLengthAsync(string key)
        {
            return await Cache.SortedSetLengthAsync(key);
        }

        /// <summary>
        /// 取集合 默认升序
        /// </summary>
        /// <param name="key"></param>
        /// <param name="start"></param>
        /// <param name="stop"></param>
        /// <param name="order">0升序 1降序</param>
        /// <returns></returns>
        public List<string> SortedSetRangeByRank(string key, long start, long stop, int order = 0)
        {
            List<string> list = new List<string>();

            var value = Cache.SortedSetRangeByRank(key, start, stop, (Order)order);

            foreach (var item in value)
                list.Add(item);

            return list;
        }

        /// <summary>
        /// 取集合 默认升序
        /// </summary>
        /// <param name="key"></param>
        /// <param name="start"></param>
        /// <param name="stop"></param>
        /// <param name="order">0升序 1降序</param>
        /// <returns></returns>
        public async Task<List<string>> SortedSetRangeByRankAsync(string key, long start, long stop, int order = 0)
        {
            List<string> list = new List<string>();

            var value = await Cache.SortedSetRangeByRankAsync(key, start, stop, (Order)order);

            foreach (var item in value)
                list.Add(item);

            return list;
        }

        /// <summary>
        /// 取集合 带score值 默认升序
        /// </summary>
        /// <param name="key"></param>
        /// <param name="start"></param>
        /// <param name="stop"></param>
        /// <param name="order">0升序 1降序</param>
        /// <returns></returns>
        public IDictionary<string, double> SortedSetRangeByRankWithScores(string key, long start, long stop, int order = 0)
        {
            IDictionary<string, double> dit = new Dictionary<string, double>();

            SortedSetEntry[] list = Cache.SortedSetRangeByRankWithScores(key, start, stop, (Order)order);
            if (list != null && list.Length > 0)
            {
                foreach (var item in list)
                    dit.Add(item.Element, item.Score);
            }
            return dit;
        }

        /// <summary>
        /// 取集合 带score值 默认升序
        /// </summary>
        /// <param name="key"></param>
        /// <param name="start"></param>
        /// <param name="stop"></param>
        /// <param name="order">0升序 1降序</param>
        /// <returns></returns>
        public async Task<IDictionary<string, double>> SortedSetRangeByRankWithScoresAsync(string key, long start, long stop, int order = 0)
        {
            IDictionary<string, double> dit = new Dictionary<string, double>();

            SortedSetEntry[] list = await Cache.SortedSetRangeByRankWithScoresAsync(key, start, stop, (Order)order);
            if (list != null && list.Length > 0)
            {
                foreach (var item in list)
                    dit.Add(item.Element, item.Score);
            }
            return dit;
        }

        /// <summary>
        ///取分值内的集合 默认升序
        /// </summary>
        /// <param name="key"></param>
        /// <param name="start"></param>
        /// <param name="stop"></param>
        /// <param name="order">0升序 1降序</param>
        /// <returns></returns>
        public List<string> SortedSetRangeByScore(string key, long start, long stop, int order = 0)
        {
            List<string> list = new List<string>();

            var value = Cache.SortedSetRangeByScore(key, start, stop, Exclude.None, (Order)order);

            foreach (var item in value)
                list.Add(item);

            return list;
        }

        /// <summary>
        ///取分值内的集合 默认升序
        /// </summary>
        /// <param name="key"></param>
        /// <param name="start"></param>
        /// <param name="stop"></param>
        /// <param name="order">0升序 1降序</param>
        /// <returns></returns>
        public async Task<List<string>> SortedSetRangeByScoreAsync(string key, long start, long stop, int order = 0)
        {
            List<string> list = new List<string>();

            var value = await Cache.SortedSetRangeByScoreAsync(key, start, stop, Exclude.None, (Order)order);

            foreach (var item in value)
                list.Add(item);

            return list;
        }

        /// <summary>
        ///取分值内的集合 默认升序
        /// </summary>
        /// <param name="key"></param>
        /// <param name="start"></param>
        /// <param name="stop"></param>
        /// <param name="order">0升序 1降序</param>
        /// <returns></returns>
        public IDictionary<string, double> SortedSetRangeByScoreWithScores(string key, long start, long stop, int order = 0)
        {
            IDictionary<string, double> dit = new Dictionary<string, double>();

            SortedSetEntry[] list = Cache.SortedSetRangeByScoreWithScores(key, start, stop, Exclude.None, (Order)order);
            if (list != null && list.Length > 0)
            {
                foreach (var item in list)
                    dit.Add(item.Element, item.Score);
            }
            return dit;
        }

        /// <summary>
        ///取分值内的集合 默认升序
        /// </summary>
        /// <param name="key"></param>
        /// <param name="start"></param>
        /// <param name="stop"></param>
        /// <param name="order">0升序 1降序</param>
        /// <returns></returns>
        public async Task<IDictionary<string, double>> SortedSetRangeByScoreWithScoresAsync(string key, long start, long stop, int order = 0)
        {
            IDictionary<string, double> dit = new Dictionary<string, double>();

            SortedSetEntry[] list = await Cache.SortedSetRangeByScoreWithScoresAsync(key, start, stop, Exclude.None, (Order)order);
            if (list != null && list.Length > 0)
            {
                foreach (var item in list)
                    dit.Add(item.Element, item.Score);
            }
            return dit;
        }

        #endregion

        #region Set  

        /// <summary>
        /// 添加无序集合操作
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public long SetAdd(string key, string[] value)
        {
            return Cache.SetAdd(key, Array.ConvertAll<string, RedisValue>(value, x => x));
        }

        /// <summary>
        /// 添加无序集合操作
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool SetAdd(string key, string value)
        {
            return Cache.SetAdd(key, value);
        }

        /// <summary>
        /// 添加无序集合操作
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public async Task<bool> SetAddAsync(string key, string value)
        {
            return await Cache.SetAddAsync(key, value);
        }

        /// <summary>
        /// 返回并删除集合操作
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public string SetPop(string key)
        {
            return Cache.SetPop(key);
        }

        /// <summary>
        /// 删除无序集合操作
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool SetRemove(string key, string value)
        {
            return Cache.SetRemove(key, value);
        }

        /// <summary>
        /// 删除无序集合操作
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public async Task<bool> SetRemoveAsync(string key, string value)
        {
            return await Cache.SetRemoveAsync(key, value);
        }

        /// <summary>
        /// 获取全部无序集合
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public HashSet<string> SetMembers(string key)
        {
            HashSet<string> list = new HashSet<string>();

            RedisValue[] value = Cache.SetMembers(key);

            if (value != null && value.Length > 0)
            {
                foreach (var item in value)
                    list.Add(item);
            }

            return list;
        }

        /// <summary>
        /// 获取全部无序集合
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public async Task<HashSet<string>> SetMembersAsync(string key)
        {
            HashSet<string> list = new HashSet<string>();

            RedisValue[] value = await Cache.SetMembersAsync(key);

            if (value != null && value.Length > 0)
            {
                foreach (var item in value)
                    list.Add(item);
            }

            return list;
        }

        #endregion

        #region sort

        /// <summary>
        ///     排序
        /// </summary>
        /// <param name="key">list/hash 要排序的列表</param>
        /// <param name="isDesc">升降</param>
        /// <param name="isAlpha">排序字段是否字符串</param>
        /// <param name="sortBypattern">*->serial</param>
        /// <param name="getpattern"> object_*->fieldname</param>
        /// <param name="skip">从第几个开始</param>
        /// <param name="take">取多少个</param>
        /// <returns></returns>
        public List<string> Sort(string key, bool isDesc, bool isAlpha,
            string sortBypattern,
            string[] getpattern, long skip = 0, long take = -1)
        {
            var order = isDesc ? Order.Descending : Order.Ascending;
            var sortType = isAlpha ? SortType.Alphabetic : SortType.Numeric;

            var result = Cache.Sort(key, skip, take, order, sortType, sortBypattern, Array.ConvertAll<string, RedisValue>(getpattern, x => x));

            List<string> list = new List<string>();

            if (result != null && result.Length > 0)
            {
                foreach (var item in result)
                    list.Add(item);
            }

            return list;
        }

        /// <summary>
        ///     排序
        /// </summary>
        /// <param name="key">list/hash 要排序的列表</param>
        /// <param name="isDesc">升降</param>
        /// <param name="isAlpha">排序字段是否字符串</param>
        /// <param name="sortBypattern">*->serial</param>
        /// <param name="getpattern"> object_*->fieldname</param>
        /// <param name="skip">从第几个开始</param>
        /// <param name="take">取多少个</param>
        /// <returns></returns>
        public async Task<List<string>> SortAsync(string key, bool isDesc, bool isAlpha,
            string sortBypattern,
            string[] getpattern, long skip = 0, long take = -1)
        {
            var order = isDesc ? Order.Descending : Order.Ascending;
            var sortType = isAlpha ? SortType.Alphabetic : SortType.Numeric;
            var result = await Cache.SortAsync(key, skip, take, order, sortType, sortBypattern, Array.ConvertAll<string, RedisValue>(getpattern, x => x));

            List<string> list = new List<string>();

            if (result != null && result.Length > 0)
            {
                foreach (var item in result)
                    list.Add(item);
            }

            return list;
        }

        #endregion

        #region sub

        public void UnsubscribeAll()
        {
            var sub = Connection.GetSubscriber();

            sub.UnsubscribeAll();
        }

        public void Subscribe(string channel, Action<string> action)
        {
            var sub = Connection.GetSubscriber();

            sub.Subscribe(channel, (cnl, message) =>
            {
                action(message);
            }, CommandFlags.FireAndForget);
        }

        /// <summary>
        /// 发布订阅
        /// </summary>
        /// <param name="channel"></param>
        /// <param name="message"></param>
        public void Publish(string channel, string message)
        {
            Cache.Publish(channel, message, CommandFlags.FireAndForget);
        }

        #endregion

        #region

        public string SerializeObject(object jsonObject)
        {
            //if (jsonObject == null) return null; //xxx:
            if (jsonObject == null) return "";

            if (jsonObject.GetType().FullName == "System.String")
                return jsonObject.ToString();

            return JsonConvert.SerializeObject(jsonObject);
        }

        public T DeserializeObject<T>(string value)
        {
            try
            {
                if (value == null) return default(T);

                if (typeof(T).FullName == "System.String")
                {
                    return (T)(object)value;
                }
                return JsonConvert.DeserializeObject<T>(value);
            }
            catch (Exception ex)
            {
                logger.Error("", ex);
                return default(T);
            }
        }

        private static T GetRefectModel<T>(Dictionary<string, string> dic) where T : class, new()
        {
            T reModel = new T();

            try
            {
                Type types = reModel.GetType();
                PropertyInfo[] cfields = types.GetProperties(BindingFlags.Public | BindingFlags.Instance);

                if (dic != null && dic.Count > 0)
                {
                    foreach (PropertyInfo info in cfields)
                    {
                        try
                        {
                            var d = dic.Where(p => p.Key == info.Name).FirstOrDefault();
                            if (!string.IsNullOrEmpty(d.Value))
                            {
                                var type = info.PropertyType;

                                if (type.FullName == "System.String")
                                    info.SetValue(reModel, d.Value.ToString(), null);
                                else
                                    info.SetValue(reModel, JsonConvert.DeserializeObject(d.Value, type), null);
                            }
                        }
                        catch (Exception ex)
                        {
                            logger.Error("GetRefectModel", ex);
                        }
                    }
                }
                else { reModel = default(T); }
            }
            catch
            {
                reModel = default(T);
            }

            return reModel;
        }

        /// <summary>
        /// 发生错误时
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void MuxerErrorMessage(object sender, RedisErrorEventArgs e)
        {
            logger.Info("ErrorMessage: ");
            //     LogHelper.Error("ErrorMessage: " + e.Message);
        }

        /// <summary>
        /// 重新建立连接之前的错误
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void MuxerConnectionRestored(object sender, ConnectionFailedEventArgs e)
        {
            logger.Info("ConnectionRestored: ");
            //       LogHelper.Error("ConnectionRestored: " + e.EndPoint);
        }

        /// <summary>
        /// 连接失败 ， 如果重新连接成功你将不会收到这个通知
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void MuxerConnectionFailed(object sender, ConnectionFailedEventArgs e)
        {
            logger.Info("重新连接：Endpoint failed: ");

            //   LogHelper.Error("重新连接：Endpoint failed: " + e.EndPoint + ", " + e.FailureType + (e.Exception == null ? "" : (", " + e.Exception.Message)));
        }

        /// <summary>
        /// 更改集群
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void MuxerHashSlotMoved(object sender, HashSlotMovedEventArgs e)
        {
            logger.Info("HashSlotMoved:NewEndPoint");

            //    LogHelper.Error("HashSlotMoved:NewEndPoint" + e.NewEndPoint + ", OldEndPoint" + e.OldEndPoint);
        }
        /// <summary>
        /// redis类库错误
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void MuxerInternalError(object sender, InternalErrorEventArgs e)
        {
            //    LogHelper.Error("InternalError:Message" + e.Exception.Message);
            logger.Info("InternalError:Message");
        }

        #endregion
    }
}